/*
在大小为 n x n 的网格 grid 上，每个单元格都有一盏灯，最初灯都处于 关闭 状态。

给你一个由灯的位置组成的二维数组 lamps ，其中 lamps[i] = [rowi, coli] 表示 打开 位于 grid[rowi][coli] 的灯。即便同一盏灯可能在 lamps 中多次列出，不会影响这盏灯处于 打开 状态。

当一盏灯处于打开状态，它将会照亮 自身所在单元格 以及同一 行 、同一 列 和两条 对角线 上的 所有其他单元格 。

另给你一个二维数组 queries ，其中 queries[j] = [rowj, colj] 。对于第 j 个查询，如果单元格 [rowj, colj] 是被照亮的，则查询结果为 1 ，否则为 0 。在第 j 次查询之后 [按照查询的顺序] ，关闭 位于单元格 grid[rowj][colj] 上及相邻 8 个方向上（与单元格 grid[rowi][coli] 共享角或边）的任何灯。

返回一个整数数组 ans 作为答案， ans[j] 应等于第 j 次查询 queries[j] 的结果，1 表示照亮，0 表示未照亮。

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/grid-illumination
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
*/
#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_map>
#include <unordered_set>
using namespace std;

class Solution
{
public:
    vector<int> gridIllumination(int n, vector<vector<int>> &lamps, vector<vector<int>> &queries)
    {
        unordered_map<int, unordered_set<int>> row, col, dg, udg;
        for (auto &p : lamps)
        {
            int x = p[0];
            int y = p[1];
            row[x].insert(y);
            col[y].insert(x);
            dg[y - x].insert(x);
            udg[y + x].insert(x);
        }

        vector<int> res;
        for (auto &q : queries)
        {
            int x = q[0], y = q[1];
            if (row[x].size() || col[y].size() || dg[y - x].size() || udg[y + x].size())
            {
                res.push_back(1);
                for (int i = max(0, x - 1); i <= min(x + 1, n - 1); i++)
                {
                    for (int j = max(0, y - 1); j <= min(y + 1, n - 1); j++)
                    {
                        row[i].erase(j);
                        col[j].erase(i);
                        dg[j - i].erase(i);
                        udg[j + i].erase(i);
                    }
                }
            }
            else
            {
                res.push_back(0);
            }
        }
        return res;
    }
};